function myPromise(excute) {
    let self = this;
    self.status = "pending";
    self.value = "";
    self.reason = ""
    self.resolvedCallbacks = [];
    self.rejectedCallbacks = [];

    function resolve(val) {
        if (self.status == "pending") {
            setTimeout(() => {
                self.status = "resolved";
                self.value = val;
                self.resolvedCallbacks.forEach(fn => fn());
            })
        }
    }

    function reject(val) {
        if (self.status == "pending") {
            setTimeout(() => {
                self.status = "rejected";
                self.value = val;
                self.rejectedCallbacks.forEach(fn => fn());
            })
        }
    }

    try {
        excute(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

myPromise.prototype.then = function (onInherit, onReject) {

    onInherit = typeof onInherit == "function" ? onInherit : (val) => val;
    onReject = typeof onReject == "function" ? onReject : (error) => { return error };
    let self = this;
    let promise = new myPromise((resolve, reject) => {
        if (self.status == "pending") {
            self.rejectedCallbacks.push(function () {
                setTimeout(() => {
                    let x = onReject(self.reason);
                    resolvePromise(promise, x, resolve, reject)
                })
            })
            self.resolvedCallbacks.push(function () {
                setTimeout(() => {
                    let x = onInherit(self.value);
                    resolvePromise(promise, x, resolve, reject)
                })
            })
        }
        if (self.status == "resolved") {
            setTimeout(() => {
                onInherit(self.value);
            })
        }
        if (self.status == "rejected") {
            setTimeout(() => {
                onReject(self.reason);
            })
        }
    })
    return promise
}

function resolvePromise(p, x, resolve, reject) {
    if (x === p && x != undefined) {
        throw TypeError("不能这样")
    }
    if (x != null && (typeof x == "function" || typeof x == "object")) {
        try {
            let then = x.then
            if (typeof then == "function") {
                then.call(x, (val) => {
                    resolvePromise(p, val, resolve, reject)
                }, (error) => {
                    reject(error)
                });
            } else {
                resolve(x)
            }
        } catch (error) {
            reject(error)
        }
    } else {
        resolve(x)
    }

}

new myPromise((resolve, reject) => {
    console.log(0)
    // setTimeout(()=>{
    resolve(1)
    // })
}).then((val) => {
    console.log(val)
    return 2
}).then((val2) => {
    console.log(val2)
})


myPromise.prototype.race = function (fns) {
    return new myPromise((resolve, reject) => {
        fns.forEach(fn => {
            fn.then((val) => {
                resolve(val)
            },(err)=>{
                reject(err)
            })
        })
    })
}

myPromise.prototype.all = function (fns) {
    return new myPromise((resolve, reject) => {
        let reason = []
        for (let i = 0; i < fns.length; i++) {
            fns[i]().then((val) => {
                reason[i] = val;
                if (reason.length === fns.length) {
                    resolve(reason)
                }
            },(err)=>{
                reject(err)
            })
        }
    })
}